﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using LZX.MEditor.LZXStatic;
using LZX.MEditor.MScriptableObject;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using Object = UnityEngine.Object;

namespace LZX.MEditor.Window.Item
{
    public class AssetItem:ItemBase
    {
        public Label Name;
        public bool IsName = true;
        public Asset Asset;
        private VisualElement BG;
        public Button btn_warning;
        public Button btn_delete;
        public bool IsDependency;
        public VisualElement Scv;
        public HashSet<BundleItem> BundleItem = new HashSet<BundleItem>();
        public AssetItem(Asset asset,VisualElement scv,BundleItem bundleItem,bool isDependency = false)
        {
            Scv = scv;
            Name = root.Q<Label>("label_name");
            Name.text = asset.Name;
            Name.RegisterCallback<ClickEvent>(OnClick);
            btn_delete = root.Q<Button>("btn_3");
            btn_delete.clicked += () => { OnDeleteClick(null);};
            btn_delete.style.backgroundImage = LZXEditorResources.GetIcon(LZXIconType.delete);
            var btn_trans = root.Q<Button>("btn_2");
            btn_trans.clicked += () => { OnTransClick(); };
            btn_trans.style.backgroundImage = LZXEditorResources.GetIcon(LZXIconType.trans);
            btn_warning = root.Q<Button>("btn_1");
            btn_warning.clicked += () => { OnWarningClick(); };
            btn_warning.style.display = DisplayStyle.None;
            btn_warning.style.backgroundImage = LZXEditorResources.GetIcon(LZXIconType.waring);
            BG = root.Q<VisualElement>("BG");
            Asset = asset;
            this.IsDependency = isDependency;
            Init(isDependency, scv,bundleItem);
            ParseBG();
            scv.Add(root);
            Name.RegisterCallback<MouseEnterEvent>(evt =>
            {
                Name.style.backgroundColor = new StyleColor(new Color(0.8f,0.8f,0.8f,1f));
            });
            Name.RegisterCallback<MouseLeaveEvent>(evt =>
            {
                if(IsDependency && !not_dependency_asset_in_bundle)
                    Name.style.backgroundColor = new StyleColor(new Color(0.3f, 0.3f, 0.3f, 1f));
                else
                    Name.style.backgroundColor = new StyleColor(Color.gray);
            });
            InitDeoendencies(bundleItem);
        }

        public List<AssetItem> dependenciesItem = new List<AssetItem>();
        public HashSet<BundleItem> referencedBundleItems = new HashSet<BundleItem>();
        public bool not_dependency_asset_in_bundle;
        private void InitDeoendencies(BundleItem bundle)
        {
            if(IsDependency)
                return;
            dependenciesItem.Clear();
            var dependencies = LZXEditorResources.GetDependencies(Asset.LoadPath);
            foreach (var dependency in dependencies)
            {
                var guid = AssetDatabase.AssetPathToGUID(dependency);
                if(bundle.Bundle.AssetGUIDs.Contains(guid))
                    continue;
                if (!LZXDependenciesManager.Instance.allAssetItem.TryGetValue(guid, out var item))
                {
                    var asset = new Asset(guid);
                    item = new AssetItem(asset , Scv,bundle ,true);
                    LZXDependenciesManager.Instance.allAssetItem.Add(asset.GUID, item);
                }
                else
                    item.Init(true, Scv,bundle);
                this.dependenciesItem.Add(item);
            }
        }

        public void Init(bool isDependency,VisualElement scv,BundleItem bundleItem)
        {
            this.IsDependency = isDependency;
            this.Scv = scv;
            if (isDependency)
            {
                //如果作为依赖资源添加
                btn_delete.style.display = DisplayStyle.None;
                Name.style.backgroundColor = new StyleColor(new Color(0.3f, 0.3f, 0.3f, 1f));
            }
            else
            {
                btn_delete.style.display = DisplayStyle.Flex;
                Name.style.backgroundColor = new StyleColor(Color.gray);
            }
            Scv.Add(this.root);
            this.referencedBundleItems.Add(bundleItem);
            InitDeoendencies(bundleItem);
            CheckWaring();
        }

        public void CheckWaring()
        {
            bool count = this.referencedBundleItems.Count > 1;
            if (count && !not_dependency_asset_in_bundle)
            {
                this.DisplayWarning();
            }
            else if (!count || not_dependency_asset_in_bundle)
            {
                this.HideWarning();
            }
        }

        private void OnWarningClick()
        {
            //暂时Debug.Log
            string bundleItems = string.Join("\n", referencedBundleItems.Select(item => item.Bundle.Name));
            Debug.Log($"Asset:[{Asset.Name}] is also include in other bundle:\n[{bundleItems}]");
        }
        private void OnClick(ClickEvent evt)
        {
            InfoWindow info = EditorWindow.GetWindow<InfoWindow>();
            info.Init(Asset);
            Object obj = AssetDatabase.LoadAssetAtPath<Object>(Asset.LoadPath);
            EditorGUIUtility.PingObject(obj);
            //Object.DestroyImmediate(obj);
        }
        public void OnDeleteClick(BundleItem item)
        {
            var window = EditorWindow.GetWindow<RightRootWindow>();
            window.DeleteAsset(this);
            //非依赖资产删除时，判断并添加其他Item的Warning
            var bundleItem = window.curSelectBundleItem;
            if (item == null)
                item = window.curSelectBundleItem;
            this.BundleItem.Remove(item);
            if (this.BundleItem.Count == 0)
            {
                this.not_dependency_asset_in_bundle = false;
            }
            foreach (var dependencyItem in dependenciesItem)
            {
                dependencyItem.referencedBundleItems.Remove(item);
                dependencyItem.CheckWaring();
            }
            CheckWaring();
        }
        private void OnTransClick()
        {
            if (IsName)
            { 
                Name.text = Asset.LoadPath;   
            }
            else
            {
                Name.text = Asset.Name;
            }
            IsName =!IsName;
        }
        public void OnSearchChanged(string context)
        {
            root.style.display = Asset.LoadPath.Contains(context,StringComparison.OrdinalIgnoreCase) ? DisplayStyle.Flex : DisplayStyle.None;
        }
        private void ParseBG()
        {
            string ext = Path.GetExtension(Asset.LoadPath);
            switch (ext)
            {
                case ".prefab":
                    BG.style.backgroundImage = LZXEditorResources.GetIcon(LZXIconType.prefab);
                    break;
                case ".mp3":
                case ".wav":
                    BG.style.backgroundImage = LZXEditorResources.GetIcon(LZXIconType.music);
                    break;
                case ".png":
                case ".jpg":
                    BG.style.backgroundImage = AssetDatabase.LoadAssetAtPath<Texture2D>(Asset.LoadPath);
                    break;
                case ".asset":
                case ".json":
                case ".txt":
                case ".bytes":
                case ".cs":
                    BG.style.backgroundImage = LZXEditorResources.GetIcon(LZXIconType.cs);
                    break;
                case ".unity":
                    BG.style.backgroundImage = LZXEditorResources.GetIcon(LZXIconType.scene);
                    break;
            }
        }

        public void DisplayWarning()
        {
            this.btn_warning.style.display = DisplayStyle.Flex;
            foreach (var bundleItem in referencedBundleItems)
            {
                bundleItem.DisplayWarning(this);
            }
        }

        public void HideWarning()
        {
            this.btn_warning.style.display = DisplayStyle.None;
            foreach (var bundleItem in referencedBundleItems)
            {
                bundleItem.HideWarning(this);
            }
        }
    }
}